package com.acwing.partition3;

import java.io.*;
import java.util.Random;

/**
 * @author `RKC`
 * @date 2022/5/2 15:22
 */
public class AC253普通平衡树 {

    private static final Random r = new Random();
    private static final int N = 100010, INF = 0x3f3f3f3f;
    private static Node[] tr = new Node[N];
    private static int n, root, idx = 0;

    private static StreamTokenizer tokenizer = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    private static PrintWriter writer = new PrintWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {
        n = nextInt();
        build();
        for (int i = 0; i < n; i++) {
            int opt = nextInt(), x = nextInt();
            if (opt == 1) root = insert(root, x);
            else if (opt == 2) root = remove(root, x);
            else if (opt == 3) writer.println(getRankByKey(root, x) - 1);
            else if (opt == 4) writer.println(getKeyByRank(root, x + 1));
            else if (opt == 5) writer.println(getPrev(root, x));
            else writer.println(getNext(root, x));
        }
        writer.flush();
    }

    private static int remove(int p, int key) {
        if (p == 0) return p;
        if (tr[p].key > key) tr[p].l = remove(tr[p].l, key);
        else if (tr[p].key < key) tr[p].r = remove(tr[p].r, key);
        else {
            //当前节点数值的出现次数大于1，则将数值出现次数减1即可
            if (tr[p].cnt > 1) tr[p].cnt--;
            else if (tr[p].l != 0 || tr[p].r != 0) {
                //当前节点只有左儿子/右儿子，则用左儿子/右儿子替代该节点；
                //当前节点有左儿子与右儿子，则不断旋转当前节点，并走到当前节点新的对应位置，直到当前节点只有左儿子/右儿子为止。
                if (tr[p].r == 0 || tr[tr[p].l].rnd > tr[tr[p].r].rnd) {
                    p = zig(p);
                    tr[p].r = remove(tr[p].r, key);
                } else {
                    p = zag(p);
                    tr[p].l = remove(tr[p].l, key);
                }
            } else {
                //当前节点没有左儿子与右儿子，则直接删除该节点
                return 0;
            }
        }
        pushup(p);
        return p;
    }

    private static int insert(int p, int key) {
        //按照BST的性质进行插入，在回溯的过程中按照大顶堆的性质进行旋转维护
        if (p == 0) return create(key);
        else if (tr[p].key == key) tr[p].cnt++;
        else if (tr[p].key > key) {
            tr[p].l = insert(tr[p].l, key);
            if (tr[tr[p].l].rnd > tr[p].rnd) p = zig(p);
        } else {
            tr[p].r = insert(tr[p].r, key);
            if (tr[tr[p].r].rnd > tr[p].rnd) p = zag(p);
        }
        pushup(p);
        return p;
    }

    private static void build() {
        tr[0] = new Node(0);
        root = create(-INF);
        tr[root].r = create(INF);
        pushup(root);
        if (tr[1].rnd < tr[2].rnd) root = zag(root);
    }

    private static void pushup(int p) {
        tr[p].size = tr[tr[p].l].size + tr[tr[p].r].size + tr[p].cnt;
    }

    private static int zig(int p) {
        //右旋
        int q = tr[p].l;
        tr[p].l = tr[q].r;
        tr[q].r = p;
        pushup(p);
        pushup(q);
        return q;
    }

    private static int zag(int p) {
        //左旋
        int q = tr[p].r;
        tr[p].r = tr[q].l;
        tr[q].l = p;
        pushup(p);
        pushup(q);
        return q;
    }

    private static int create(int key) {
        //创建一个treap节点，设置val为随机值
        tr[++idx] = new Node(key);
        tr[idx].rnd = r.nextInt(n);
        tr[idx].cnt = tr[idx].size = 1;
        return idx;
    }

    private static int getRankByKey(int p, int key) {
        //根据数值找排名
        if (p == 0) return 0;
        if (tr[p].key == key) return tr[tr[p].l].size + 1;
        if (key < tr[p].key) return getRankByKey(tr[p].l, key);
        return tr[tr[p].l].size + tr[p].cnt + getRankByKey(tr[p].r, key);
    }

    private static int getKeyByRank(int p, int rank) {
        //根据排名找数值
        if (p == 0) return INF;
        if (tr[tr[p].l].size >= rank) return getKeyByRank(tr[p].l, rank);
        if (tr[tr[p].l].size + tr[p].cnt >= rank) return tr[p].key;
        return getKeyByRank(tr[p].r, rank - tr[tr[p].l].size - tr[p].cnt);
    }

    private static int getPrev(int p, int key) {
        //找到严格小于key的最大的数
        if (p == 0) return -INF;
        if (tr[p].key >= key) return getPrev(tr[p].l, key);
        return Math.max(tr[p].key, getPrev(tr[p].r, key));
    }

    private static int getNext(int p, int key) {
        //找到严格大于key的最小的数
        if (p == 0) return INF;
        if (tr[p].key <= key) return getNext(tr[p].r, key);
        return Math.min(tr[p].key, getNext(tr[p].l, key));
    }

    private static class Node {
        //l和r分别为左右子节点的指针，key为关键字，rnd为随机值，cnt表示当前key重复的次数，size表示左右子树和自身节点总和
        private int l, r, key, rnd, cnt, size;

        public Node(int key) {
            this.key = key;
        }
    }

    private static int nextInt() throws IOException {
        tokenizer.nextToken();
        return (int) tokenizer.nval;
    }
}
